package com.yangjiayu.service.impl;

import cn.hutool.json.JSONUtil;
import com.yangjiayu.bean.SearXNGResponse;
import com.yangjiayu.bean.SearchResult;
import com.yangjiayu.service.SearXngService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @Classname SearXngServiceImpl
 * @Description TODO
 * @Date 2025/8/15 13:36
 * @Created by YangJiaYu
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SearXngServiceImpl implements SearXngService {

    @Value("${internet.websearch.searxng.url}")
    private String SEARXNG_URL;

    @Value("${internet.websearch.searxng.count}")
    private Integer COUNT;

    private final OkHttpClient okHttpClient;

//    @Override
//    public List<SearchResult> search(String query) {
//        HttpUrl url = HttpUrl.parse(SEARXNG_URL)
//            .newBuilder()
//            .addQueryParameter("q",query)
//            .addQueryParameter("format","json")
//            .build();
//
//        log.info("搜索的url地址为: "+url.url());
//
//        // 构建request
//        Request request = new Request.Builder()
//            .url(url).build();
//        // 发送请求
//        try (Response response =okHttpClient.newCall(request).execute()){
//            // 判断请求是否成功还是失败
//            if(!response.isSuccessful()){
//                throw new RuntimeException("请求失败:HTTP+"+response.code());
//            }
//
//            // 获得相应的数据
//            if(response.body() != null){
//                String responseBody = response.body().string();
//                SearXNGResponse searXNGResponse = JSONUtil.toBean(responseBody, SearXNGResponse.class);
//                return dealResults(searXNGResponse.getResults());
//            }
//            log.info("搜索失败：{}",response.message());
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//        return List.of();
//    }

    @Override
    public List<SearchResult> search(String query) {

        //Java 代码缺了 UTF-8 URL-encode，导致关键词被截断成“马”，返回的就是“马”而非“马斯克”。
        String encoded = URLEncoder.encode(query, StandardCharsets.UTF_8);

//        String engines = "baidu,sogou,bing";   // 只把确定可用的放进来
//        HttpUrl url = HttpUrl.parse(SEARXNG_URL)
//            .newBuilder()
//            .addQueryParameter("q", URLEncoder.encode(query, StandardCharsets.UTF_8))
//            .addQueryParameter("format", "json")
//            .addQueryParameter("engines", engines)
//            .build();

        // 构建url
        HttpUrl url = HttpUrl.get(SEARXNG_URL)
            .newBuilder()
            .addQueryParameter("q", encoded)
            .addQueryParameter("format", "json")
//            .addQueryParameter("engines","bing")
            .build();

        log.info("搜索的url地址为：" + url.url());

        // 构建request
        Request request = new Request.Builder()
            .url(url)
            .build();

        // 发送请求
        try (Response response = okHttpClient.newCall(request).execute()) {

            // 判断请求是否成功还是失败
            if (!response.isSuccessful()) throw new RuntimeException("请求失败: HTTP " + response.code());

            // 获得响应的数据
            if (response.body() != null) {
                String responseBody = response.body().string();
                log.info("SearXNG原始返回：{}", responseBody);   // 加这一行

                SearXNGResponse searXNGResponse = JSONUtil.toBean(responseBody, SearXNGResponse.class);

                return dealResults(searXNGResponse.getResults());
            }
            log.error("搜索失败：{}", response.message());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return Collections.emptyList();
    }


    /**
     * 处理结果集，截取限制的个数
     * @param results
     * @return
     */
    private List<SearchResult> dealResults(List<SearchResult>results){

        if (CollectionUtils.isEmpty(results)) {
            return Collections.emptyList();
        }
        List<SearchResult> list = results.subList(0,Math.min(COUNT,results.size()))
            .parallelStream()
            .sorted(Comparator.comparing(SearchResult::getScore).reversed())
            .limit(COUNT).toList();
        return list;
    }
}
